package com.imedway.ihe.dtz.xds.repository;

import java.io.File;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.activation.DataHandler;
import javax.xml.namespace.QName;

import org.openehealth.ipf.commons.ihe.xds.core.ebxml.EbXMLAssociation;
import org.openehealth.ipf.commons.ihe.xds.core.ebxml.EbXMLExtrinsicObject;
import org.openehealth.ipf.commons.ihe.xds.core.ebxml.EbXMLRegistryError;
import org.openehealth.ipf.commons.ihe.xds.core.ebxml.EbXMLRegistryPackage;
import org.openehealth.ipf.commons.ihe.xds.core.ebxml.ebxml30.EbXMLProvideAndRegisterDocumentSetRequest30;
import org.openehealth.ipf.commons.ihe.xds.core.ebxml.ebxml30.EbXMLRegistryError30;
import org.openehealth.ipf.commons.ihe.xds.core.ebxml.ebxml30.EbXMLRegistryResponse30;
import org.openehealth.ipf.commons.ihe.xds.core.ebxml.ebxml30.ProvideAndRegisterDocumentSetRequestType;
import org.openehealth.ipf.commons.ihe.xds.core.metadata.AssociationType;
import org.openehealth.ipf.commons.ihe.xds.core.responses.ErrorCode;
import org.openehealth.ipf.commons.ihe.xds.core.responses.Severity;
import org.openehealth.ipf.commons.ihe.xds.core.responses.Status;
import org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.lcm.SubmitObjectsRequest;
import org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.rs.RegistryError;
import org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.rs.RegistryErrorList;
import org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.rs.RegistryResponseType;
import org.openehealth.ipf.commons.ihe.xds.iti42.Iti42PortType;
import org.springframework.beans.factory.annotation.Autowired;

import com.imedway.ihe.dtz.xds.cons.ConstProperties;
import com.imedway.ihe.dtz.xds.cons.SysConsts;
import com.imedway.ihe.dtz.xds.dao.DataDao;
import com.imedway.ihe.dtz.xds.dto.XdsDto;
import com.imedway.ihe.dtz.xds.entity.IheXdsFileInfo;
import com.imedway.ihe.dtz.xds.util.DhccFileUtils;

import cn.hutool.core.lang.UUID;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Iti41Repository_backup {

	@Autowired
	private ConstProperties constProperties;

	public RegistryResponseType run(ProvideAndRegisterDocumentSetRequestType body) {
		
		
		RegistryResponseType registryResponseType = new RegistryResponseType();
		registryResponseType.setRegistryErrorList(new RegistryErrorList());
		List<EbXMLRegistryError> registryError = new ArrayList<EbXMLRegistryError>();
		EbXMLRegistryResponse30 ebXMLRegistryResponse30 = new EbXMLRegistryResponse30(registryResponseType);
		
		boolean flag = true;
		try {

			EbXMLProvideAndRegisterDocumentSetRequest30 ebXMLBody = new EbXMLProvideAndRegisterDocumentSetRequest30(body);

			List<EbXMLAssociation> ebXMLAssociationList=ebXMLBody.getAssociations();
			for(EbXMLAssociation ebXMLAssociation:ebXMLAssociationList) {
				log.debug(ebXMLAssociation.getId());
				log.debug(ebXMLAssociation.getTarget());
				log.debug(ebXMLAssociation.getSource());
				
				flag = this.isOrNotExitedPatient(ebXMLAssociation,ebXMLBody);
	            if(flag==true) {
					AssociationType associationType = ebXMLAssociation.getAssociationType();
					log.warn(associationType.name());
					//3.0这样写xml urn:oasis:names:tc:ebxml-regrep:AssociationType:HasMember
					//2.1直接写xml HasMember
					switch (associationType) {
					case SUBMIT_ASSOCIATION:
						// Document 提交 新增
						flag = this.documentSUBMIT_ASSOCIATION(ebXMLAssociation,ebXMLBody);
						break;
					case REPLACE:
						// Document Replacement 替换
						flag = this.documentREPLACE(ebXMLAssociation,ebXMLBody);
						break;
					case APPEND:
						// Document Addendum 追加、补遗
						flag = this.documentAPPEND(ebXMLAssociation,ebXMLBody);
						break;
					case TRANSFORM:
						// Document Transformation 转换
						flag = this.documentTRANSFORM(ebXMLAssociation,ebXMLBody);
						break;
					case HAS_MEMBER:
						// Document 有成员
						flag = this.documentHAS_MEMBER(ebXMLAssociation,ebXMLBody);
						break;
					case SIGNS:
						// Document 签名
						flag = this.documentSIGNS(ebXMLAssociation,ebXMLBody);
						break;
					case IS_SNAPSHOT_OF:
						// Document 快照
						flag = this.documentIS_SNAPSHOT_OF(ebXMLAssociation,ebXMLBody);
						break;
					case UPDATE_AVAILABILITY_STATUS:
						// Document 更新状态
						flag = this.documentUPDATE_AVAILABILITY_STATUS(ebXMLAssociation,ebXMLBody);
						break;
					case TRANSFORM_AND_REPLACE:
						// Document 转换替换
						flag = this.documentTRANSFORM_AND_REPLACE(ebXMLAssociation,ebXMLBody);
						break;
					default:
						break;
					}
	            }else {
	            	EbXMLRegistryError30 re = new EbXMLRegistryError30(new RegistryError());	            		            	
	            	re.setSeverity(Severity.WARNING);
	            	re.setErrorCode(ErrorCode.PATIENT_ID_DOES_NOT_MATCH.getOpcode());
	            	re.setCodeContext("患者不存在");
	            	registryError.add(re);
	            }				
			}			
		} catch (Exception e) {
			log.info(e.getMessage(), e);
			flag = false;
		}
		
		ebXMLRegistryResponse30.setErrors(registryError);
		ebXMLRegistryResponse30.setStatus(flag ? Status.SUCCESS : Status.FAILURE);
		
		return registryResponseType;
		
		
	}
	public boolean iti42(SubmitObjectsRequest submitObjectsRequest) {
		boolean flag = true;
		URL wsdlUrl;
		try {
			wsdlUrl = new URL("http://localhost:8080/services/iti42?wsdl");
			QName serviceName = new QName("http://service.ihe.imedway.com/", "Iti42PortTypeImplService");
			javax.xml.ws.Service service = javax.xml.ws.Service.create(wsdlUrl, serviceName);
			Iti42PortType myWebService = service.getPort(Iti42PortType.class);
			RegistryResponseType registryResponseType = myWebService
					.documentRegistryRegisterDocumentSetB(submitObjectsRequest);
			log.info(registryResponseType.getRequestId());

		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		return flag;
	}


	public boolean documentSUBMIT_ASSOCIATION(EbXMLAssociation ebXMLAssociation, EbXMLProvideAndRegisterDocumentSetRequest30 ebXMLBody) {
		boolean flag = true;
		log.info("documentSUBMIT_ASSOCIATION");
		try {	
			
			EbXMLExtrinsicObject ebXMLExtrinsicObject = getFileMineTypeByDocumentID(ebXMLAssociation.getTarget(), ebXMLBody.getExtrinsicObjects());						
			log.debug(ebXMLExtrinsicObject.getId());
			
			EbXMLRegistryPackage ebXMLRegistryPackage = getEbXMLRegistryPackageByID(ebXMLAssociation.getSource(), ebXMLBody.getRegistryPackages());
			DataHandler dataHandler =ebXMLBody.getDocuments().get(ebXMLAssociation.getTarget());					
			InputStream inputStream = dataHandler.getInputStream();
			String uuidString=UUID.fastUUID().toString();
			String filePath = constProperties.getFileRootPath() + uuidString+"."+	DhccFileUtils.getFileType(ebXMLExtrinsicObject.getMimeType());
			log.info(filePath);
			DhccFileUtils.saveToFile(inputStream, new File(filePath));
										
			String XDSSubmissionSetsourceId = ebXMLExtrinsicObject.getExternalIdentifierValue(SysConsts.XDSDocumentEntryuniqueIdidentificationScheme);
			String XDSSubmissionSetpatientId = ebXMLExtrinsicObject.getExternalIdentifierValue(SysConsts.XDSDocumentEntrypatientIdidentificationScheme);
			
			log.debug(uuidString);
			log.debug(XDSSubmissionSetsourceId);
			log.debug(XDSSubmissionSetpatientId);
			
//			EbXMLSubmitObjectsRequest30 ebXMLSubmitObjectsRequest30= new EbXMLSubmitObjectsRequest30(ebXMLBody.getInternal().getSubmitObjectsRequest());

			ebXMLRegistryPackage.addExternalIdentifier(uuidString, SysConsts.XDSSubmissionSetuniqueIdidentificationScheme , "XDSSubmissionSet.uniqueId");
			ebXMLRegistryPackage.addExternalIdentifier(XDSSubmissionSetsourceId,SysConsts.XDSSubmissionSetsourceIdidentificationScheme , "XDSSubmissionSet.sourceId");
			ebXMLRegistryPackage.addExternalIdentifier(XDSSubmissionSetpatientId,SysConsts.XDSSubmissionSetpatientIdidentificationScheme , "XDSSubmissionSet.patientId");
//			ebXMLBody.addRegistryPackage(ebXMLRegistryPackage);
			// toiti42
			// Document Registry
			flag = this.iti42(ebXMLBody.getInternal().getSubmitObjectsRequest());

		} catch (Exception e) {
			log.info(e.getMessage(), e);
		}
	
		return flag;
	}

	public boolean documentREPLACE(EbXMLAssociation ebXMLAssociation, EbXMLProvideAndRegisterDocumentSetRequest30 ebXMLBody) {
		log.info("documentREPLACE");
		boolean flag = true;
		try {
//			EbXMLSubmitObjectsRequest30 ebXMLbody= new EbXMLSubmitObjectsRequest30(ebXMLBody.getInternal().getSubmitObjectsRequest());
			EbXMLExtrinsicObject ebXMLExtrinsicObject = getFileMineTypeByDocumentID(ebXMLAssociation.getTarget(), ebXMLBody.getExtrinsicObjects());
			String filePath = constProperties.getFileRootPath() + ebXMLExtrinsicObject.getExternalIdentifierValue(SysConsts.XDSDocumentEntryuniqueIdidentificationScheme)+"."+	
			DhccFileUtils.getFileType(getFileMineTypeByDocumentID(ebXMLAssociation.getTarget(), ebXMLBody.getExtrinsicObjects()).getMimeType());		
			DataHandler dataHandler =ebXMLBody.getDocuments().get(ebXMLAssociation.getTarget());					
			InputStream inputStream = dataHandler.getInputStream();
			log.info(filePath);
//			DhccFileUtils.replaceToFile(inputStream, new File(filePath));
			
			flag = this.iti42(ebXMLBody.getInternal().getSubmitObjectsRequest());	
			
		} catch (Exception e) {
			log.info(e.getMessage(), e);
		}
	
		return flag;
	}

	public boolean documentAPPEND(EbXMLAssociation ebXMLAssociation, EbXMLProvideAndRegisterDocumentSetRequest30 ebXMLBody) {
		log.info("documentAPPEND");
		boolean flag = true;
		try {
//			EbXMLSubmitObjectsRequest30 ebXMLbody= new EbXMLSubmitObjectsRequest30(ebXMLBody.getInternal().getSubmitObjectsRequest());
			EbXMLExtrinsicObject ebXMLExtrinsicObject = getFileMineTypeByDocumentID(ebXMLAssociation.getTarget(), ebXMLBody.getExtrinsicObjects());
			String filePath = constProperties.getFileRootPath() + ebXMLExtrinsicObject.getExternalIdentifierValue(SysConsts.XDSDocumentEntryuniqueIdidentificationScheme)+"."+	
			DhccFileUtils.getFileType(getFileMineTypeByDocumentID(ebXMLAssociation.getTarget(), ebXMLBody.getExtrinsicObjects()).getMimeType());		
			DataHandler dataHandler =ebXMLBody.getDocuments().get(ebXMLAssociation.getTarget());					
			InputStream inputStream = dataHandler.getInputStream();
			log.info(filePath);
			DhccFileUtils.appendToFile(inputStream, new File(filePath));
			
			flag = this.iti42(ebXMLBody.getInternal().getSubmitObjectsRequest());	
			
		} catch (Exception e) {
			log.info(e.getMessage(), e);
		}
		return flag;
	}

	public boolean documentTRANSFORM(EbXMLAssociation ebXMLAssociation, EbXMLProvideAndRegisterDocumentSetRequest30 ebXMLBody) {
		log.info("documentTRANSFORM");
		boolean flag = true;
		try {
//			EbXMLSubmitObjectsRequest30 ebXMLbody= new EbXMLSubmitObjectsRequest30(ebXMLBody.getInternal().getSubmitObjectsRequest());
			EbXMLExtrinsicObject ebXMLExtrinsicObject = getFileMineTypeByDocumentID(ebXMLAssociation.getTarget(), ebXMLBody.getExtrinsicObjects());
			String filePath = constProperties.getFileRootPath() + ebXMLExtrinsicObject.getExternalIdentifierValue(SysConsts.XDSDocumentEntryuniqueIdidentificationScheme)+"."+	
			DhccFileUtils.getFileType(getFileMineTypeByDocumentID(ebXMLAssociation.getTarget(), ebXMLBody.getExtrinsicObjects()).getMimeType());		
			DataHandler dataHandler =ebXMLBody.getDocuments().get(ebXMLAssociation.getTarget());					
			InputStream inputStream = dataHandler.getInputStream();
			log.info(filePath);
			DhccFileUtils.transformToFile(inputStream, new File(filePath));
			
			flag = this.iti42(ebXMLBody.getInternal().getSubmitObjectsRequest());
									
		} catch (Exception e) {
			log.info(e.getMessage(), e);
		}
		return flag;
	}

	//仅处理了根目录或一级关系
	public boolean documentHAS_MEMBER(EbXMLAssociation ebXMLAssociation, EbXMLProvideAndRegisterDocumentSetRequest30 ebXMLBody) {
		log.info("documentHAS_MEMBER");
		boolean flag = true;
		try {
			
			//新增文件夹(根目录下一级关系)
			EbXMLRegistryPackage ebXMLRegistryPackage = getEbXMLRegistryPackageByID(ebXMLAssociation.getTarget(),
					ebXMLBody.getRegistryPackages());
			if (ebXMLRegistryPackage != null) {
				String folderName = ebXMLRegistryPackage.getName().getValue();
				EbXMLRegistryPackage ebXMLRegistryPackageSource = getEbXMLRegistryPackageByID(ebXMLAssociation.getSource(),
						ebXMLBody.getRegistryPackages());
				String folderNameSource = ebXMLRegistryPackageSource.getName().getValue();
				if("Repository".equals(folderNameSource)) {
					DhccFileUtils.createDirectory(constProperties.getFileRootPath()+folderName);
				}else {
					log.info("不在根目录下");
				}
			}else {
				//新增文件到文件夹
				EbXMLExtrinsicObject ebXMLExtrinsicObject = getFileMineTypeByDocumentID(ebXMLAssociation.getTarget(), ebXMLBody.getExtrinsicObjects());
				DataHandler dataHandler =ebXMLBody.getDocuments().get(ebXMLAssociation.getTarget());	
				EbXMLRegistryPackage ebXMLRegistryPackageSource = getEbXMLRegistryPackageByID(ebXMLAssociation.getSource(),
						ebXMLBody.getRegistryPackages());
				String folderNameSource = ebXMLRegistryPackageSource.getName().getValue();
				InputStream inputStream = dataHandler.getInputStream();
				String filePath = constProperties.getFileRootPath() + folderNameSource+"\\"+ebXMLExtrinsicObject.getId()+"."+
				     DhccFileUtils.getFileType(ebXMLExtrinsicObject.getMimeType());
				log.info(filePath);
				DhccFileUtils.saveToFile(inputStream, new File(filePath));
			}
			
			flag = this.iti42(ebXMLBody.getInternal().getSubmitObjectsRequest());

		} catch (Exception e) {
			log.info(e.getMessage(), e);
		}
		
		return flag;
	}
	
	public boolean documentSIGNS(EbXMLAssociation ebXMLAssociation, EbXMLProvideAndRegisterDocumentSetRequest30 ebXMLBody) {
		log.info("documentSIGNS");
		boolean flag = true;
		try {
			
		} catch (Exception e) {
			log.info(e.getMessage(), e);
		}
		
		return flag;
	}
	public boolean documentIS_SNAPSHOT_OF(EbXMLAssociation ebXMLAssociation, EbXMLProvideAndRegisterDocumentSetRequest30 ebXMLBody) {
		log.info("documentIS_SNAPSHOT_OF");
		boolean flag = true;
		try {
			
		} catch (Exception e) {
			log.info(e.getMessage(), e);
		}
		
		return flag;
	}
	public boolean documentUPDATE_AVAILABILITY_STATUS(EbXMLAssociation ebXMLAssociation, EbXMLProvideAndRegisterDocumentSetRequest30 ebXMLBody) {
		log.info("documentUPDATE_AVAILABILITY_STATUS");
		boolean flag = true;
		try {
			
		} catch (Exception e) {
			log.info(e.getMessage(), e);
		}
		
		return flag;
	}
	public boolean documentTRANSFORM_AND_REPLACE(EbXMLAssociation ebXMLAssociation, EbXMLProvideAndRegisterDocumentSetRequest30 ebXMLBody) {
		log.info("documentTRANSFORM_AND_REPLACE");
		boolean flag = true;
		try {
			
		} catch (Exception e) {
			log.info(e.getMessage(), e);
		}
		
		return flag;
	}
	
	public boolean isOrNotExitedPatient(EbXMLAssociation ebXMLAssociation, EbXMLProvideAndRegisterDocumentSetRequest30 ebXMLBody) {
		log.info("isOrNotExitedPatient");
		boolean flag = true;
		try {
			EbXMLExtrinsicObject ebXMLExtrinsicObject = getFileMineTypeByDocumentID(ebXMLAssociation.getTarget(), ebXMLBody.getExtrinsicObjects());
			String XDSSubmissionSetpatientId = ebXMLExtrinsicObject.getExternalIdentifierValue(SysConsts.XDSDocumentEntrypatientIdidentificationScheme);
			List<IheXdsFileInfo> iheXdsInfoFileList=this.find(XDSSubmissionSetpatientId);
			if(iheXdsInfoFileList.isEmpty()) {
				flag = false;
			}
			
		} catch (Exception e) {
			log.info(e.getMessage(), e);
		}
		
		return flag;
	}
	
	public List<IheXdsFileInfo> find(String patientId) throws SQLException {
		XdsDto xdsDto = new XdsDto();
		List<IheXdsFileInfo> iheXdsInfoFileList = new ArrayList<IheXdsFileInfo>();
		IheXdsFileInfo iheXdsFileInfo =new IheXdsFileInfo();
		iheXdsFileInfo.setPatientId(patientId);
		iheXdsInfoFileList.add(iheXdsFileInfo);
		xdsDto.setIheXdsInfoList(iheXdsInfoFileList);
		DataDao dataDao = new DataDao();
		return dataDao.findFileData(xdsDto);
	}
	
	public static EbXMLExtrinsicObject getFileMineTypeByDocumentID(String id,List<EbXMLExtrinsicObject> list) {
		EbXMLExtrinsicObject ebXMLExtrinsicObject=null;
		for(EbXMLExtrinsicObject o:list) {
			if(o.getId().equals(id)) {
				ebXMLExtrinsicObject=o;
				break;
			}
		}
		return ebXMLExtrinsicObject;
	
	}
	
	public static EbXMLRegistryPackage getEbXMLRegistryPackageByID(String id,List<EbXMLRegistryPackage> list) {
		EbXMLRegistryPackage ebXMLRegistryPackage=null;
		for(EbXMLRegistryPackage o:list) {
			if(o.getId().equals(id)) {
				ebXMLRegistryPackage=o;
				break;
			}
		}
		return ebXMLRegistryPackage;
	
	}
}
